import axios from 'axios'
import store from '@/store/index.js'
import JSONbig from 'json-bigint'
import router from '@/router'
const http = axios.create({
  // 用户基准地址
  baseURL: 'http://ttapi.research.itcast.cn/',
  transformResponse: [function (data) {
    // data => 原始的后台返回的json字符串数据
    // 这里的方法，会覆盖axios默认对于返回结果的处理，默认进行的是 JSON.parse
    // 需要进行的是 JSONbig.parse
    // 后台返回的可能不是json字符串，JSONbig 解析就会报错，不合理的，需要处理
    try {
      return JSONbig.parse(data)
    } catch (err) {
      // 如果解析不了，说明不是json样式，原样输出
      console.log(err)
    }
  }]
})
// 添加请求拦截器
http.interceptors.request.use(function (config) {
  // 在发送请求之前做些什么
  const token = store.state.tokenInfo.token
  if (token) {
    config.headers.Authorization = `Bearer ${token}`
  }
  return config
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error)
})

// 响应拦截器
http.interceptors.response.use(function (response) {
  // 对响应数据做点什么(成功响应) response 就是成功的响应res
  return response
}, async function (error) {
  // 对响应错误做点什么
  // console.dir(error)
  if (error.response.status === 401) {
    console.log('token过期了，一小时过去了，需要通过refresh_token去刷新token')
    const refreshToken = store.state.tokenInfo.refresh_token
    // 判断有无refreshToken
    if (refreshToken) {
      try {
        console.log('存在refreshToken，需要进行刷新token操作')
        // 1.发送请求，进行刷新token操作，获取新的token
        // 注意！！！：这边发请求前，不要http实例，用它自动会在请求前帮你携带token(会覆盖你的refresh_token)
        // 用axios直接发送请求
        const res = await axios({
          method: 'put',
          url: 'http://ttapi.research.itcast.cn/app/v1_0/authorizations',
          headers: {
            Authorization: `Bearer ${refreshToken}`
          }
        })
        // console.log(res)
        // 2.将新token更新到vuex中去
        const newToken = res.data.data.token
        store.commit('setTokenInfo', {
          token: newToken,
          refresh_token: refreshToken
        })
        // 3.重新发送刚才的请求，http，自动携带token(携带的是新token)
        // error.config就是之前用于请求的配置对象，可以直接给http使用
        // console.dir(error)
        return http(error.config)
      } catch {
        // refreshtoken过期了，跳转到登录页
        // 清除无效的token对象
        store.commit('removeToken')
        // 跳转到登录页，跳转完，再跳回来
        router.push({
          path: '/login',
          query: {
            backto: router.currentRoute.fullPath
          }
        })
      }
    } else {
      // 没有refreshToken，直接去登录，将来还能回来
      // router.currentRoute 指向当前路由信息对象 === 等价于之前页面中用的this.$route
      // token已经过期了，需要清除掉
      store.commit('removeToken')
      router.push({
        path: '/login',
        query: {
          backto: router.currentRoute.fullPath // 请求的参数
        }
      })
    }
  }
  return Promise.reject(error)
})
export default http
